import { set } from 'lodash-es';
import React, { lazy, Suspense } from 'react';
import { useRoutes } from 'react-router-dom';
import Loading from '@/components/loading';
// 约定式路由，可不使用
/**
 * 根据 pages 目录生成路径配置
 */
function generatePathConfig() {
  // 扫描 src/pages 下的所有具有路由文件
  const modules = import.meta.glob('/src/pages/**/$*.{js,jsx}');
  const pathConfig = {};
  Object.keys(modules).forEach((filePath) => {
    const routePath = filePath
      // 去除 src/pages 不相关的字符
      .replace('/src/pages/', '')
      // 去除文件名后缀
      .replace(/.jsx?/, '')
      // 转换动态路由 $[foo].tsx => :foo
      .replace(/\$\[([\w-]+)]/, ':$1')
      // 转换以 $ 开头的文件
      .replace(/\$([\w-]+)/, '$1')
      // 以目录分隔
      .split('/');
    // 使用 lodash.set 合并为一个对象
    set(pathConfig, routePath, modules[filePath]);
  });
  return pathConfig;
}

/**
 * @description: 形成路由组件
 */
function wrapSuspense(importer) {
  if (!importer) return;
  // 使用 React.lazy 包裹 () => import() 语法
  const Com = lazy(importer);
  // 结合 Suspense
  return (
    <Suspense fallback={<Loading />}>
      <Com />
    </Suspense>
  );
}

function mapPathConfigToRoute(cg) {
  return Object.entries(cg).map(([routePath, child]) => {
    // 看是否是方法
    if (typeof child === 'function') {
      // 表示当前根路由
      const isIndex = routePath === 'index';
      const element = wrapSuspense(child);
      const res = {
        index: isIndex,
      };
      if (!isIndex) {
        res.path = routePath;
      }
      if (element) {
        res.element = element;
      }
      return res;
    }
    // 否根路由
    const { $, ...rest } = child;
    const ele = wrapSuspense($);
    const rs = {
      path: routePath,
      children: mapPathConfigToRoute(rest),
    };
    if (ele) {
      rs.element = ele;
    }
    return rs;
  });
}
function generateRouteConfig() {
  const pathConfig = generatePathConfig();
  // 提取跟路由的 layout
  return [...mapPathConfigToRoute(pathConfig)];
}

const routeConfig = generateRouteConfig();

const PageRoutes = () => {
  return useRoutes(routeConfig);
};

export default PageRoutes;

// webpack中可以使用glob进行文件路径的解析
